/**
 * 分页响应类
 */
export class PageResponse<T> {
    totalElements = 0;
    page = 0;
    size = 10;
    content: T[] = [];
    orderBy = 'id';
    direction: 'asc' | 'desc' = 'desc';
    totalPages = 0;

    constructor() {}

    setTotalElements(totalElements: number): void {
        this.totalElements = totalElements;
        this.totalPages = Math.ceil(this.totalElements / this.size);
    }

    /**
     * 从请求对象创建分页响应对象
     */
    static of<T>(req: any): PageResponse<T> {
        const {page, size, orderBy, direction} = PageResponse.getPageAndSize(req);
        const pageResponse = new PageResponse<T>();
        pageResponse.page = page;
        pageResponse.size = size;
        pageResponse.orderBy = orderBy;
        pageResponse.direction = direction;
        return pageResponse;
    }

    /**
     * 从请求对象获取分页参数
     */
    static getPageAndSize(req: any): {
        page: number;
        size: number;
        orderBy: string;
        direction: 'asc' | 'desc';
    } {
        const page = parseInt(req.query.page || '0');
        const size = parseInt(req.query.size || '10');
        const orderBy = req.query.orderBy || 'id';
        const direction = (req.query.direction || 'asc') as 'asc' | 'desc';
        return {page, size, orderBy, direction};
    }
}

/**
 * 验证错误类
 */
export class ValidationError extends Error {
    constructor(message: string) {
        super(message);
        this.name = 'ValidationError';
    }
}

// 类型定义
export type Direction = 'asc' | 'desc';

export type Sql = {
    selectSql: string;
    formWhereSql: string;
    orderBySql: string | null;
    countInSql: string | null;
};

export type PageRequest = {
    page: number;
    size: number;
    orderBy?: string;
    direction?: Direction;
};

export type OrderBy = {
    orderBy?: string;
    direction?: Direction;
};

export interface ParentConfig<T = any> {
    parentId: string;
    parentObject: string;
    parentTable: string;
    parentIdName: string;
    parentClass?: new () => T;
}

/**
 * 表配置类
 */
export class TableConfig {
    table: string;
    columnSet: string[] = [];
    idName: string = 'id';
    idAutoCreate = true;
    jsonColumn: string[] = [];
    createTime: string = '';
    updateTime: string = '';
    createReturn = true;
    parents: ParentConfig[] = [];

    constructor(table: string, columnSet: string[]) {
        this.table = table;
        this.columnSet = columnSet;
    }
}

// 工具函数
export const isString = (val: unknown): val is string => typeof val === 'string';

export const isArray = (val: unknown): val is any[] => Array.isArray(val);

export const isObject = (val: unknown): val is Record<string, any> =>
    val !== null && typeof val === 'object' && !Array.isArray(val);

export function anyToEntity<T extends object>(val: unknown, newEntity: () => T): T {
    if (!val || typeof val !== 'object') {
        return newEntity();
    }

    const entity = newEntity();
    Object.keys(entity).forEach(key => {
        if (key in (val as Record<string, unknown>)) {
            // @ts-ignore
            entity[key] = (val as Record<string, unknown>)[key];
        }
    });
    return entity;
}

export function anyToEntities<T extends object>(values: unknown[], newEntity: () => T): T[] {
    if (!values || !Array.isArray(values)) {
        return [];
    }

    return values.map(value => anyToEntity(value, newEntity));
}